#pragma once

// ref:https://github.com/modyuan/AudioRecorder

#ifdef WINDOWS
#pragma warning(disable:4819)
#endif


extern "C" {
#define __STDC_CONSTANT_MACROS
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/avutil.h>
#include <libavutil/file.h>
#include <libavutil/time.h>
#include <libavutil/audio_fifo.h>
#include <libavutil/imgutils.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
#include <libavdevice/avdevice.h>

}
#include <string>
#include <atomic>
#include <thread>
#include <cstdint>


class AudioRecorder {

private:
    std::string _outfile;
    std::string _deviceName;
    std::string _failReason;

    AVFormatContext *_audioInFormatCtx;
    AVStream        *_audioInStream;
    AVCodecContext  *_audioInCodecCtx;

    SwrContext      *_audioConverter;
    AVAudioFifo     *_audioFifo;

    AVFormatContext *_audioOutFormatCtx;
    AVStream        *_audioOutStream;
    AVCodecContext  *_audioOutCodecCtx;

    std::atomic_bool     _isRun;
    std::thread         *_audioThread;

    void startEncode();

public:

    AudioRecorder(std::string filepath, std::string device)
            :_outfile(filepath),_deviceName(device),_failReason(""),_isRun(false){}

    void open();
    void start();
    void stop();

    ~AudioRecorder() {
        stop();
    }

    std::string failReason() { return _failReason; }
};
